/*
* cameracontrol
* Copyright (C) 2010 Stefano Fornari
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by
* the Free Software Foundation with the addition of the following permission
* added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
* WORK IN WHICH THE COPYRIGHT IS OWNED BY Stefano Fornari, Stefano Fornari
* DISCLAIMS THE WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program; if not, see http://www.gnu.org/licenses or write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA.
*/
package ste.cameracontrol.ui;
import java.awt.Image;
import java.awt.event.ComponentAdapter;
import java.io.IOException;
import ste.cameracontrol.CameraController;
import ste.cameracontrol.Photo;
/**
*
* @author ste
*/
public class ImageFrame extends BaseFrame {
private final String[] ZOOM_VALUES = {
"Fit", "10%", "25%", "50%", "75%", "100%",
"150%", "200%", "300%", "500%", "1000%"
};
public static final int MAX_ZOOM = 1000;
public static final String ICON_IMAGE_SAVED = "images/image-saved-16x16.png";
public static final String ZOOM_FIT_VALUE = "Fit";
public static final String ZOOM_ORIGINAL_VALUE = "100%";
private ImagePanel jpegPanel;
private Photo photo;
/** Creates new ImageFrame */
public ImageFrame(Photo photo) {
this.photo = photo;
initCustomComponents();
setTitle(photo.getName());
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
scrollPaneJpeg = new javax.swing.JScrollPane(jpegPanel);
bottomPanel = new javax.swing.JPanel();
buttonsPanel = new javax.swing.JPanel();
saveButton = new javax.swing.JButton();
rawIcon = new javax.swing.JLabel();
jpegIcon = new javax.swing.JLabel();
jPanel1 = new javax.swing.JPanel();
zoomFitButton = new javax.swing.JButton();
zoom100Button = new javax.swing.JButton();
zoomScrollbar = new javax.swing.JScrollBar();
zoomValueBox = new javax.swing.JComboBox(ZOOM_VALUES);
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
setIconImage(getImage(ICON_CAMERACONTROL));
scrollPaneJpeg.setName("scrollpane"); // NOI18N
getContentPane().add(scrollPaneJpeg, java.awt.BorderLayout.CENTER);
bottomPanel.setLayout(new javax.swing.BoxLayout(bottomPanel, javax.swing.BoxLayout.LINE_AXIS));
buttonsPanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEADING, 2, 3));
saveButton.setFont(new java.awt.Font("Arial", 0, 10));
saveButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/image-not-saved-16x16.png"))); // NOI18N
saveButton.setText("Save");
saveButton.setMaximumSize(new java.awt.Dimension(56, 20));
saveButton.setMinimumSize(new java.awt.Dimension(56, 20));
saveButton.setPreferredSize(new java.awt.Dimension(56, 20));
saveButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
saveButtonActionPerformed(evt);
}
});
buttonsPanel.add(saveButton);
rawIcon.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/raw.png"))); // NOI18N
buttonsPanel.add(rawIcon);
jpegIcon.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/jpeg.png"))); // NOI18N
buttonsPanel.add(jpegIcon);
bottomPanel.add(buttonsPanel);
jPanel1.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.RIGHT, 0, 3));
zoomFitButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/zoom-fit-best-16x16.png"))); // NOI18N
zoomFitButton.setMaximumSize(new java.awt.Dimension(20, 20));
zoomFitButton.setMinimumSize(new java.awt.Dimension(20, 20));
zoomFitButton.setPreferredSize(new java.awt.Dimension(20, 20));
zoomFitButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
zoomFitButtonActionPerformed(evt);
}
});
jPanel1.add(zoomFitButton);
zoom100Button.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/zoom-original-16x16.png"))); // NOI18N
zoom100Button.setMaximumSize(new java.awt.Dimension(20, 20));
zoom100Button.setMinimumSize(new java.awt.Dimension(20, 20));
zoom100Button.setPreferredSize(new java.awt.Dimension(20, 20));
zoom100Button.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
zoom100ButtonActionPerformed(evt);
}
});
jPanel1.add(zoom100Button);
zoomScrollbar.setMaximum(1000);
zoomScrollbar.setMinimum(10);
zoomScrollbar.setOrientation(javax.swing.JScrollBar.HORIZONTAL);
zoomScrollbar.setUnitIncrement(10);
zoomScrollbar.setValue(100);
zoomScrollbar.setVisibleAmount(1);
zoomScrollbar.setPreferredSize(new java.awt.Dimension(100, 20));
zoomScrollbar.addAdjustmentListener(new java.awt.event.AdjustmentListener() {
public void adjustmentValueChanged(java.awt.event.AdjustmentEvent evt) {
zoomScrollbarAdjustmentValueChanged(evt);
}
});
jPanel1.add(zoomScrollbar);
zoomValueBox.setEditable(true);
zoomValueBox.setFont(new java.awt.Font("Arial", 0, 10));
zoomValueBox.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
zoomValueBox.setMaximumSize(new java.awt.Dimension(75, 19));
zoomValueBox.setMinimumSize(new java.awt.Dimension(75, 19));
zoomValueBox.setPreferredSize(new java.awt.Dimension(75, 20));
zoomValueBox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
zoomValueBoxActionPerformed(evt);
}
});
jPanel1.add(zoomValueBox);
bottomPanel.add(jPanel1);
getContentPane().add(bottomPanel, java.awt.BorderLayout.SOUTH);
pack();
}// </editor-fold>//GEN-END:initComponents
/**
* Set the zoom value for the picture. The zoom value is an int representing
* the zoom percentage (e.g. 10%, 100%).
*
* @param zoom the zoom percentage
*/
private void setZoomValue(double zoom) {
zoomValueBox.setSelectedItem(((int)zoom) + "%");
jpegPanel.setScale(zoom / 100);
jpegPanel.revalidate();
zoomScrollbar.setValue((int)zoom);
}
public void setZoomValue(String zoomValue) {
if (zoomValue.endsWith("%")) {
zoomValue = zoomValue.substring(0, zoomValue.length()-1);
}
double zoom = 100;
if (ZOOM_FIT_VALUE.equals(zoomValue)) {
Image img = jpegPanel.getImage();
if (img == null) {
return;
}
int width = img.getWidth(null)+2;
int height = img.getHeight(null)+2;
double zoomW = 100, zoomH = 100;
if (width > scrollPaneJpeg.getWidth()) {
zoomW = (int)((double)scrollPaneJpeg.getWidth()/(double)width*100);
}
if (height > scrollPaneJpeg.getHeight()) {
zoomH = (int)((double)scrollPaneJpeg.getHeight()/(double)height*100);
}
zoom = Math.min(zoomW, zoomH);
} else {
zoom = Integer.parseInt(zoomValue);
if ((zoom < 1) || (zoom > MAX_ZOOM)) {
throw new IllegalArgumentException("zoom out of range [1," + MAX_ZOOM + "]");
}
}
setZoomValue(zoom);
}
private void zoomValueBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_zoomValueBoxActionPerformed
String zoomValue = (String)zoomValueBox.getSelectedItem();
if (zoomValue == null) {
return;
}
setZoomValue(zoomValue);
}//GEN-LAST:event_zoomValueBoxActionPerformed
private void zoomScrollbarAdjustmentValueChanged(java.awt.event.AdjustmentEvent evt) {//GEN-FIRST:event_zoomScrollbarAdjustmentValueChanged
setZoomValue(evt.getValue());
}//GEN-LAST:event_zoomScrollbarAdjustmentValueChanged
private void zoomFitButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_zoomFitButtonActionPerformed
setZoomValue(ZOOM_FIT_VALUE);
}//GEN-LAST:event_zoomFitButtonActionPerformed
private void zoom100ButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_zoom100ButtonActionPerformed
setZoomValue(ZOOM_ORIGINAL_VALUE);
}//GEN-LAST:event_zoom100ButtonActionPerformed
private void saveButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveButtonActionPerformed
try {
CameraController.getInstance().savePhoto(photo);
saveButton.setIcon(getIcon(ICON_IMAGE_SAVED));
} catch (IOException e) {
error("Error saving " + photo.getName(), e);
}
}//GEN-LAST:event_saveButtonActionPerformed
private void initCustomComponents() {
jpegPanel = new ImagePanel();
initComponents();
if (photo.hasJpeg()) {
jpegPanel.setImage(photo.getJpegImage());
jpegIcon.setVisible(true);
} else {
jpegIcon.setVisible(false);
}
rawIcon.setVisible(photo.hasRaw());
pack();
scrollPaneJpeg.addComponentListener(
new ComponentAdapter() {
public void componentResized(java.awt.event.ComponentEvent evt) {
//
// We want to set the zoom to fit the first time the panel
// is displayed. The sizing of the view port is deferred
// from the sizing of the rest of the frame, therefore
// we need to intercept componentResized. We than remove the
// listener since after the first time we do not need it any
// more.
//
setZoomValue(ZOOM_FIT_VALUE);
scrollPaneJpeg.removeComponentListener(this);
}
}
);
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JPanel bottomPanel;
private javax.swing.JPanel buttonsPanel;
private javax.swing.JPanel jPanel1;
private javax.swing.JLabel jpegIcon;
private javax.swing.JLabel rawIcon;
private javax.swing.JButton saveButton;
private javax.swing.JScrollPane scrollPaneJpeg;
private javax.swing.JButton zoom100Button;
private javax.swing.JButton zoomFitButton;
private javax.swing.JScrollBar zoomScrollbar;
private javax.swing.JComboBox zoomValueBox;
// End of variables declaration//GEN-END:variables
}